import { isUndef } from '../util/lang'
import { addDomEvent, offset } from '../util/dom'

const DEFAULT_OPTION = {
  // 横轴方向初始化位置
  startX: 0,
  // 纵轴方向初始化位置
  startY: 0,
  // 横向滚动
  scrollX: false,
  // 纵向滚动
  scrollY: true,
  // 是否开启滚动边界动画
  bounce: true,
  // 设置回弹动画的动画时长
  bounceTime: 800,
  // 只有在屏幕上快速滑动的时间小于 `momentumLimitTime`，才能开启 momentum 动画
  momentumLimitTime: 300,
  // 只有在屏幕上快速滑动的距离大于 `momentumLimitDistance`，才能开启 momentum 动画
  momentumLimitDistance: 15,
  // 设置 momentum 动画的动画时长
  swipeTime: 2500,
  // 设置当运行 momentum 动画时，超过边缘后的回弹整个动画时间
  swipeBounceTime: 500,
  // 表示 momentum 动画的减速度
  deceleration: 0.0015,
  // 屏幕滑动过程中实时派发 scroll 事件时机
  probeType: 1,
  // 是否使用 CSS3 transition 动画
  useTransition: true,
  // 是否允许滚动
  enable: true,

  // 下拉刷新
  pullDownRefresh: false,
  // 上拉加载
  pullUpLoad: false,
  // 轮播
  snap: false
}

// feature配置示例
// pullDownRefresh: {
//   threshold: 60,
//   stop: 40
// },
// pullUpLoad: {
//   threshold: 0,
// },
// snap {
//   threshold: 30,
//   interval: 3000,
//   loop: true,
//   autoPlay: true,
//   stepX: 100,
//   stepY: 100
// }

export function initMixin (GScroll) {
  GScroll.prototype._init = function (options) {
    isUndef(options) && (options = {})

    this._handleOptions(options)

    this._addDomEvents()

    this.refresh()
  }

  GScroll.prototype._addDomEvents = function () {
    let eventOperation = addDomEvent
    this._handleDomEvents(eventOperation)
  }

  GScroll.prototype._handleDomEvents = function (eventOperation) {
    let target = this.wrapper
    eventOperation(target, 'touchstart', this)
    eventOperation(target, 'touchmove', this)
    eventOperation(target, 'touchcancel', this)
    eventOperation(target, 'touchend', this)

    eventOperation(target, 'transitionend', this)
  }

  GScroll.prototype.handleEvent = function (e) {
    switch (e.type) {
      case 'touchstart':
        this._start(e)
        break
      case 'touchmove':
        this._move(e)
        break
      case 'touchend':
      case 'touchcancel':
        this._end(e)
        break
      case 'transitionend':
        this._transitionEnd(e)
        break
    }
  }

  GScroll.prototype._handleOptions = function (options) {
    this.options = Object.assign({}, DEFAULT_OPTION, options)

    this.hasHorizontalScroll = this.options.scrollX
    this.hasVerticalScroll = this.options.scrollY
    this.x = 0
    this.y = 0

    this.enabled = true

    if (this.options.pullDownRefresh) {
      this.openPullDown()
    }
    if (this.options.pullUpLoad) {
      this.openPullUp()
    }
    if (this.options.snap) {
      this._initSnap()
    }
  }

  GScroll.prototype.refresh = function (e) {
    this.wrapperWidth = this.wrapper.offsetWidth
    this.wrapperHeight = this.wrapper.offsetHeight
    this.scrollerWidth = this.scroller.offsetWidth
    this.scrollerHeight = this.scroller.offsetHeight

    this.minScrollX = 0
    this.maxScrollX = this.wrapperWidth - this.scrollerWidth
    this.minScrollY = 0
    this.maxScrollY = this.wrapperHeight - this.scrollerHeight

    this.wrapperOffset = offset(this.wrapper)

    this.trigger('refresh')
  }

  GScroll.prototype.enable = function () {
    this.enabled = true
  }

  GScroll.prototype.disable = function () {
    this.enabled = false
  }
}
